package public

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
)

//FfmPegTool 管理ffm的接口
type FfmPegTool struct {
}

// PictoVido 图片转换成视频
func (ft *FfmPegTool) PictoVido(inputPath string, outPath string) {
	//ffmpeg -r 60 -f image2 -s 1920x1080 -i pic%04d.png -vcodec libx264 -crf 25  -pix_fmt yuv420p test.mp4
	//    ffmpeg -f image2 -i image%d.png tt.mp4
	//ffmpeg -r 1 -i image%d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4

	//cmd := exec.Command(t.FfmpegPath, "-threads", "4", "-i", t.PullStream, "-max_muxing_queue_size", "200", "-profile:v", "baseline", "-level", "4.0", "-vcodec", t.Coding, "-b:v", t.Bps, "-s", t.Dpi, "-acodec", "copy", "-tune", "zerolatency", "-f", "flv", "-y", t.PushStream)
	//ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
	// -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
	var param string
	param += "D:\\local\\ffmpeg\\bin\\ffmpeg.exe"

	param += " -r " //每秒传输帧数(Frames Per Second)
	param += "25"

	//	param += " -f "
	//	param += "image2"

	//	param += " -s " //帧尺寸就是720×480高
	//	param += "1920x1080"

	param += " -i " //输入您要处理的视频文件路径
	param += inputPath

	param += " -c:v " //codec编解码方式
	param += "libx264"

	param += " -crf " //is the quality, lower means better quality, 15-25 is usually good
	param += "25"

	param += " -pix_fmt " //specifies the pixel format, change this as neededspecifies the pixel format, change this as needed
	param += "yuv420p"

	param += " -f mp4 "
	param += " -y "
	param += outPath

	ft.runCommand(param)
}

// WebmToMp4 视频格式转换
func (ft *FfmPegTool) WebmToMp4(inputPath string, outPath string) bool {
	var param string
	param += "D:\\local\\ffmpeg\\bin\\ffmpeg.exe"
	param += "  -threads "
	param += " 2 "

	param += " -i "
	param += inputPath
	param += " -r" //每秒传输帧数(Frames Per Second)
	param += " 25 "

	//param += " -vcodec copy"
	param += " -vcodec  libx264 "

	param += " -crf 23 "
	param += " -preset slow    "

	param += " -movflags faststart  "

	param += " -b:v 1000k  -bufsize 2000k "

	param += " -s 720x480 "
	param += " -filter:v  setpts=0.8*PTS" //
	param += " -f mp4 "
	param += " -y "
	param += outPath

	ft.runCommand(param)

	return true
}

//runCommand cmd命令执行
func (ft *FfmPegTool) runCommand(param string) bool {

	log.Println("Cmd.Run >>>>>>>>>>>>>>>>>", param)

	var cmd *exec.Cmd = nil

	if runtime.GOOS == "windows" {
		cmd = exec.Command("cmd", "/C", param)

	} else {
		cmd = exec.Command("bash", "-c", param)
	}
	if runtime.GOOS == "windows" {
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
	}

	if err := cmd.Run(); err != nil {
		log.Println("Error: ", err)
		fmt.Println("Error: ", err)
		return false

	}
	//Run starts the specified command and waits for it to complete.
	return true

}

// Mp4ToRtmp Mp4ToRtmp
func (ft *FfmPegTool) Mp4ToRtmp(filePath string, rtmpPath string) bool {

	if len(filePath) == 0 || len(rtmpPath) == 0 {
		log.Println("Mp4ToRtmp input is null")
		return false
	}

	var param string
	if runtime.GOOS == "windows" {
		param += "D:\\local\\ffmpeg\\bin\\ffmpeg.exe"

	} else {
		param += "ffmpeg"
	}
	//param += "  -threads "
	//param += " 2 "

	param += " -re "

	param += "-stream_loop 500 " //循环播放

	//是否支持播放列表
	var concatFlag bool = false
	if concatFlag == true {
		param += " -f concat -i playlist.txt "
		//		cat mylist.txt
		//		file '/path/to/file1'
		//		file '/path/to/file2'
		//		file '/path/to/file3'
	} else {
		param += " -i "

		param += filePath
	}

	//添加文字
	var txtFlag bool = false
	if txtFlag == true {
		param += " -vf"
		param += " drawtext=fontcolor=white:fontsize=40:fontfile=msyh.ttf:text='武汉加油':x=0:y=100 "

	}
	param += " -c copy "

	//https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
	//	param += " -bufsize 4000k"
	//	param += " -maxrate 500k"
	param += " -f flv "
	//https://blog.mangege.com/tech/2015/02/15/1.html
	param += rtmpPath

	go ft.runCommand(param)

	return true
}

// KillByName KillByName
func (ft *FfmPegTool) KillByName(name string) bool {
	if runtime.GOOS == "windows" {
		return true

	}

	//ps -ef | grep ffmpeg | grep -v grep | awk '{print $2}' | xargs kill
	//param:="ps -ef | grep ffmpeg | grep -v grep | awk  ' {print $2}' | xargs kill"
	//	param := "killall "
	//	param += name
	cmd := exec.Command("killall", name)
	if err := cmd.Run(); err != nil {
		return false
	}
	return true
}

// Mp4ToRtmpTaskByConcat mp4 to rtmp
func (ft *FfmPegTool) Mp4ToRtmpTaskByConcat(playlist string, rtmpPath string) int {

	if ft.PathExist(playlist) == false {
		return -2
	}

	///////////////////////单个文件//////////////////////////
	var param string = "ffmpeg"

	param += " -re "

	param += "-stream_loop 500   -safe 0  " //循环播放

	//是否支持播放列表
	param += " -f concat -i "
	param += playlist
	//		cat mylist.txt
	//		file '/path/to/file1'
	//		file '/path/to/file2'
	//		file '/path/to/file3'
	//bug1 https://superuser.com/questions/1069556/ffmpeg-concat-demuxer-unsafe-file-name/1069569

	//添加文字
	var txtFlag bool = false
	if txtFlag == true {
		param += " -vf"
		param += " drawtext=fontcolor=white:fontsize=40:fontfile=msyh.ttf:text='武汉加油':x=0:y=100 "

	}
	param += " -c copy "

	param += " -f flv "

	param += rtmpPath

	go ft.runCommand(param)

	return 0
}

// PathExist 判断路径是否存在
func (ft *FfmPegTool) PathExist(_path string) bool {
	_, err := os.Stat(_path)
	if err != nil && os.IsNotExist(err) {
		return false
	}
	return true
}

// OnePicWithMP3toMp4 为音频添加封面
//https://stackoverflow.com/questions/32340770/ffmpeg-adding-jpg-and-mp3-together-to-make-a-video-for-upload-on-youtube
//ffmpeg -loop 1 -i *.jpg -i *.mp3 -c:v libx264 -tune stillimage -c:a aac -strict experimental -b:a 192k -pix_fmt yuv420p -shortest out.mp4
//https://www.5yun.org/ffmpeg-jiang-yin-pin-tu-pian-zhuan-huan-cheng-shi-pin.html
//ffmpeg -r 15 -f image2 -loop 1 -i 1.jpg -i test.mp3  -pix_fmt yuvj420p -t 60 -vcodec libx264 test.mp4
//BUG1
//picPath  图片质量太大 不行,测试368k的不行
//https://askubuntu.com/questions/868283/image-audio-mp4-how-to-make-video-smaller
//bu2:jpg图片格式有问题。

func (ft *FfmPegTool) OnePicWithMP3toMp4(picPath string, mp3Path string, outPath string) {
	fmt.Println("OnePicWithMP3toMp4", picPath, mp3Path, outPath)
	var param string
	if runtime.GOOS == "windows" {
		param += "D:\\local\\ffmpeg\\bin\\ffmpeg.exe"

	} else {
		param += "ffmpeg"
	}
	param += "  -threads "
	param += " 2 "

	param += "  -thread_queue_size "
	param += " 1024 "

	param += " -f image2 "

	param += " 	-loop 1 " //如果不够60秒.t时长不会重复的

	param += " -i " //pic
	param += picPath

	param += " -i " //mp3
	param += mp3Path
	//添加后出问题
	//param += " -pix_fmt " //specifies the pixel format, change this as neededspecifies the pixel format, change this as needed
	//param += "yuvj420p"
	//添加后出问题

	//https://askubuntu.com/questions/868283/image-audio-mp4-how-to-make-video-smaller
	param += " -bufsize 1024k"
	//-s = The actual size of the video output.
	//param += "-s 1280x720"
	// Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

	param += " -t " //这个是图片转换成视频后持续的时间长度，必须指定，单位为秒，不然会无限制生成视频时间长度
	param += "55"
	//bug 如果mp3内容小于60秒，无法产生文件.失败，大于60秒被截取了。看来还是通过字数来限制时间。
	//Set the video codec. This is an alias for -codec:v.
	//视频编解码：-c:v libx264
	//https://trac.ffmpeg.org/wiki/Encode/H.264
	param += " -vcodec libx264 "

	//Set the audio codec. This is an alias for -codec:a.
	//音频编解码 -c:a

	//param += " -acodec copy  "

	param += " -acodec aac  "

	//bitrate  -b:a 192k
	//bitrate  -b:v 800k
	//param += " -b:a 192k "
	//param += " -b:v 2567k "
	param += " -shortest "
	//http://ffmpeg.org/ffmpeg.html#Advanced-options

	// -t duration (input/output)
	// When used as an input option (before -i), limit the duration of data read from the input file
	// 	The following examples are all valid time duration:

	// ‘55’
	// 55 seconds

	// ‘12:03:45’
	// 12 hours, 03 minutes and 45 seconds

	// ‘23.189’
	// 23.189 seconds
	// -s 1920×1080

	param += " -f mp4 "
	param += " -y "
	param += outPath
	fmt.Println(param)
	ft.runCommand(param)

}
